#include "AsioIoContextPool.hpp"
#include <iostream>
#include <memory>
#include <thread>
AsioIoContextPool::AsioIoContextPool(std::size_t size)
    : _ioContext(size), _works(size), _nextIoContext(0) {
  for (int i = 0; i < size; ++i) {
    _works[i] = std::make_unique<Work>(_ioContext[i]);
  }
  for (int i = 0; i < size; ++i) {
    _threads.emplace_back([this, i] { _ioContext[i].run(); });
  }
}

boost::asio::io_context &AsioIoContextPool::GetIoContext() {
  auto &service = _ioContext[_nextIoContext++];
  _nextIoContext = _nextIoContext % _ioContext.size();
  return service;
}

void AsioIoContextPool::Stop() {
  for (auto &work : _works) {
    work->get_io_context().stop();
    work.reset();
  }

  for (auto &t : _threads) {
    if (t.joinable()) {
      t.join();
    }
  }
}

AsioIoContextPool ::~AsioIoContextPool() { Stop(); }
